#include "bsp_uart.h"
#include "bsp_beep.h"


void uart_init(void)
{
	/* UART 时钟源选择 */
	CCM->CSCDR1 &= ~(1 << 6);		/* 选择pll3_80m作为时钟源 */
	CCM->CSCDR1 &= ~(0x3f << 0);	/* 选择1分频 */

	uart_disable(UART1);

	uart_io_int();					/* UART IO复用 */
	uart_reset();					/* UART 软件复位 */

	/* UARTx_UCR1 */
	UART1->UCR1 = 0;			/* 关闭UART1, 关闭UART1自动波特率检测 */

	/* UARTx_UCR2 */
	UART1->UCR2 &= ~(1 << 8);	/* Parity 奇偶校验不启用 */
	UART1->UCR2 &= ~(1 << 6);	/* StopBit 停止位，1个停止位 */
	UART1->UCR2 |= (1 << 14);	/* 忽略RTS pin 引脚 */
	UART1->UCR2 |= (1 << 5);	/* WordSize 字宽，8个数据位 */
	UART1->UCR2 |= (1 << 2);	/* TXEN 使能Tx */
	UART1->UCR2 |= (1 << 1);	/* RXEN 使能Rx */

	/* UARTx_UCR3 */
	UART1->UCR3 |= (1 << 2);	/* I.MX6ULL手册指出此位必须被设置为1 */

	/* UART波特率设置 */
	UART1->UFCR &= ~(7 << 7);
	UART1->UFCR |= (5 << 7);	/* 1分频 */
	UART1->UBIR |= (71 & 0xFFFF);
	UART1->UBMR |= (3124 & 0xFFFF);

	uart_enable(UART1);
}

void uart_io_int(void)
{
	/* 0x10B0 = 0001 0000 1011 0000
	 * bit[0]		SRE			0 低压摆率
	 * bit[2:1]		Reserved	00 保留未使用
	 * bit[5:3]		DSE			110 驱动能力DSE_6_R0_6 — R0/6
	 * bit[7:6]		SPEED		10  medium(100MHz)
	 * bit[10:8]	Reserved	000 保留未使用
	 * bit[11]		ODE			0 Open-Drain 开漏输出（推挽输出）
	 * bit[12]		PKE			1 Pull/Keeper使能
	 * bit[13]		PUE			0 Pull/Keeper Select 选择，0选择Keeper
	 * bit[15:14]	PUS			00 Pull UP/Down Config, 00选择100K Ohm Pull Down
	 */

	/* UART1_TX_DATA IO复用 */
	IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0);
	IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX, 0x10B0);

	/* UART1_RX_DATA IO复用 */
	IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0);
	IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX, 0x10B0);
}

void uart_enable(UART_Type *base)
{
	base->UCR1 |= (1 << 0);
}

void uart_disable(UART_Type *base)
{
	base->UCR1 &= ~(1 << 0);
}

unsigned char getc(void)
{
	unsigned char c;

	while((UART1->USR2 & (1 << 0)) == 0);	/* 检查UART RDR标志位，确认Rx是否完成 */
	c = (UART1->URXD & 0xFF);

	return c;
}

void putc(unsigned char c)
{

	/* 检查UART TXDC标志位，确认Tx是否完成 */
	while((UART1->USR2 & (1 << 3)) == 0);
	//UART1->UTXD = (c & 0x0F);
	UART1->UTXD = (c & 0xFF);
}

void puts(char *str)
{
	char *p = str;
	while(*p){
		putc(*p++);
	}
}

void uart_reset(void)
{
	// UART1->USR2 &= ~(1 << 0);				/* UART 软件复位 */
	// while((UART1->USR2 & (1<< 0)) == 0);	/* 等待UART软件复位完成 */
	UART1->UCR2 &= ~(1 << 0);				/* UART 软件复位 */
	while((UART1->UCR2 & (1<< 0)) == 0);	/* 等待UART软件复位完成 */
}

void raise(void)
{
	/* 避免编译器报错 */
}